﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using psafth.FSR.Lapcounter;
using System.IO;

namespace ConsoleApplication1
{
    using System;
    using System.Collections.Generic;
    using System.Management;
    using System.ComponentModel;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;

    class Program
    {
        static string status = "8e 02 33 00 0d 8d ad 00 00 01 00 01 04 57 34 00 00 03 04 08 8a 29 00 04 08 58 d4 23 9d 96 db 04 00 05 02 5c 00 06 02 80 00 08 02 00 00 81 04 be 13 04 00 8f";
        static byte[] statusBytes = new byte[] { 0x8e, 0x02, 0x1f, 0x00, 0x76, 0xc4, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x2b, 0x00, 0x07, 0x02, 0x20, 0x00, 0x0c, 0x01, 0x77, 0x06, 0x01, 0x00, 0x81, 0x04, 0xbe, 0x13, 0x04, 0x00, 0x8f };
        static byte[] passingFirst = new byte[] { 0x8e, 0x02, 0x33, 0x00, 0xeb, 0x1d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x04, 0x9d, 0x09, 0x00, 0x00, 0x03, 0x04 };
        static byte[] passingSecond = new byte[] { 0x04, 0x08 };
        static byte[] passingThird = new byte[] { 0x05, 0x02, 0x5f, 0x00, 0x06, 0x02, 0x2e, 0x00, 0x08, 0x02, 0x00, 0x00, 0x81, 0x04, 0xbe, 0x13, 0x04, 0x00, 0x8f };

        public static byte[] ToSend
        {
            get;
            set;
        }

        static void Main(string[] args)
        {
            BackgroundWorker _bw = new BackgroundWorker();

            _bw.DoWork += _bw_DoWork;
            _bw.ProgressChanged += _bw_ProgressChanged;

            _bw.RunWorkerAsync();

            while (!_bw.CancellationPending || _bw.IsBusy)
            {

            }
        }

        static void _bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(-3);
            //return epoch.AddMilliseconds(unixTime / 1000);

            TimeSpan epoch = DateTime.Now.Subtract(start);

            byte[] transponderId = (byte[])e.UserState;

            byte[] time = BitConverter.GetBytes(epoch.TotalMilliseconds / 1000);

            byte[] passingBytes = new byte[passingFirst.Length + time.Length + passingSecond.Length + transponderId.Length + passingThird.Length];
            System.Buffer.BlockCopy(passingFirst, 0, passingBytes, 0, passingFirst.Length);
            System.Buffer.BlockCopy(transponderId, 0, passingBytes, passingFirst.Length, transponderId.Length);
            System.Buffer.BlockCopy(passingSecond, 0, passingBytes, passingFirst.Length + transponderId.Length, passingSecond.Length);
            System.Buffer.BlockCopy(time, 0, passingBytes, passingFirst.Length + passingSecond.Length + transponderId.Length, time.Length);
            System.Buffer.BlockCopy(passingThird, 0, passingBytes, passingFirst.Length + passingSecond.Length + transponderId.Length + time.Length, passingThird.Length);

            Console.WriteLine(BitConverter.ToInt32(transponderId, 0));

            ToSend = passingBytes;
        }



        private static void _bw_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            while (true)
            {
                //try
                //{
                    // Create a TcpClient.
                    // Note, for this client to work you need to have a TcpServer
                    // connected to the same address as specified by the server, port
                    // combination

                    TcpListener server = new TcpListener(IPAddress.Any, 5403);

                    server.Stop();

                    server.Start();

                    //try
                    //{
                        BackgroundWorker fredrik = new TransponderPassing() { TransponderId = 4777687 };
                        BackgroundWorker johan = new TransponderPassing() { TransponderId = 3581439 };
                        BackgroundWorker per = new TransponderPassing() { TransponderId = 9075509 };
                        BackgroundWorker marth = new TransponderPassing() { TransponderId = 9530045 };
                        BackgroundWorker daniel = new TransponderPassing() { TransponderId = 8929082 };
                        BackgroundWorker anders = new TransponderPassing() { TransponderId = 4917087 };
                        BackgroundWorker fredrick = new TransponderPassing() { TransponderId = 6006846 };
                        BackgroundWorker staffan = new TransponderPassing() { TransponderId = 9221969 };
                        BackgroundWorker peter = new TransponderPassing() { TransponderId = 9796583 };
                        BackgroundWorker unknown = new TransponderPassing() { TransponderId = 1234567 };


                        fredrik.ProgressChanged += _bw_ProgressChanged;
                        johan.ProgressChanged += _bw_ProgressChanged;
                        per.ProgressChanged += _bw_ProgressChanged;
                        daniel.ProgressChanged += _bw_ProgressChanged;
                        anders.ProgressChanged += _bw_ProgressChanged;
                        fredrick.ProgressChanged += _bw_ProgressChanged;
                        marth.ProgressChanged += _bw_ProgressChanged;
                        peter.ProgressChanged += _bw_ProgressChanged;
                        unknown.ProgressChanged += _bw_ProgressChanged;

                        fredrik.WorkerReportsProgress = true;
                        johan.WorkerReportsProgress = true;
                        per.WorkerReportsProgress = true;
                        daniel.WorkerReportsProgress = true;
                        anders.WorkerReportsProgress = true;
                        fredrick.WorkerReportsProgress = true;
                        marth.WorkerReportsProgress = true;
                        peter.WorkerReportsProgress = true;
                        unknown.WorkerReportsProgress = true;

                        TcpClient client = server.AcceptTcpClient(); // Get client connection

                        client.ReceiveTimeout = 15000;
                        client.SendTimeout = 15000;

                        fredrik.RunWorkerAsync();
                        Thread.Sleep(100);
                        johan.RunWorkerAsync();
                        Thread.Sleep(100);
                        per.RunWorkerAsync();
                        Thread.Sleep(100);
                        daniel.RunWorkerAsync();
                        Thread.Sleep(100);
                        anders.RunWorkerAsync();
                        Thread.Sleep(100);
                        fredrick.RunWorkerAsync();
                        Thread.Sleep(100);
                        marth.RunWorkerAsync();
                        Thread.Sleep(100);
                        peter.RunWorkerAsync();
                        Thread.Sleep(100);
                        //unknown.RunWorkerAsync();

                        NetworkStream netStream = client.GetStream();

                        netStream.ReadTimeout = 15000;
                        netStream.WriteTimeout = 15000;

                        while (client.Connected)
                        {
                            netStream.Write(statusBytes, 0, statusBytes.Length);
                            netStream.Flush();

                            break;
                        }

                        while (client.Connected)
                        {
                            if (ToSend != null)
                            {
                                if (netStream.CanWrite)
                                {
                                    try
                                    {
                                        netStream.Write(ToSend, 0, ToSend.Length);
                                        netStream.Flush();
                                        ToSend = null;
                                    }
                                    catch (Exception ex)
                                    {
                                        client = server.AcceptTcpClient();
                                        netStream = client.GetStream();
                                    }
                                }
                            }
                        }
                //    }
                //    catch (Exception ex)
                //    {
                //        //throw ex;
                //    }
                //}
                //catch (Exception ex)
                //{
                //    //throw ex;
                //}

            }
        }

        //static List<USBDeviceInfo> GetUSBDevices()
        //{
        //    List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

        //    ManagementObjectCollection collection;
        //    using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub"))
        //        collection = searcher.Get();

        //    foreach (var device in collection)
        //    {
        //        devices.Add(new USBDeviceInfo(
        //        (string)device.GetPropertyValue("DeviceID"),
        //        (string)device.GetPropertyValue("PNPDeviceID"),
        //        (string)device.GetPropertyValue("Description"),
        //        (string)device.GetPropertyValue("Name")
        //        ));
        //    }

        //    collection.Dispose();
        //    return devices;
        //}
    }

    //class USBDeviceInfo
    //{
    //    public USBDeviceInfo(string deviceID, string pnpDeviceID, string description, string name)
    //    {
    //        this.DeviceID = deviceID;
    //        this.PnpDeviceID = pnpDeviceID;
    //        this.Description = description;
    //        this.Name = name;
    //    }
    //    public string DeviceID { get; private set; }
    //    public string PnpDeviceID { get; private set; }
    //    public string Description { get; private set; }
    //    public string Name { get; private set; }
    //}
    //}
    //class Program
    //{
    //    static void Main(string[] args)
    //    {
    //        List<RaceCompetitor> Competitors = new List<RaceCompetitor>();

    //        Random r = new Random();

    //        RaceCompetitor r1 = new RaceCompetitor("Fredrik", "Svensson", "S8-49", 4777687, 1);

    //        int num = r.Next(10, 85);

    //        for (int i = 0; i < num; i++)
    //        {
    //            r1.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }

    //        RaceCompetitor r2 = new RaceCompetitor("Krister", "Eng", "S8-5", 3592932, 2);

    //        num = r.Next(10, 85);
    //        for (int i = 0; i < num; i++)
    //        {
    //            r2.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }

    //        RaceCompetitor r3 = new RaceCompetitor("Johan", "Eng", "S8-6", 4777687, 3);

    //        num = r.Next(10, 85);

    //        for (int i = 0; i < num; i++)
    //        {
    //            r3.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }

    //        RaceCompetitor r4 = new RaceCompetitor("Per", "Nilsson", "S8-95", 3592932, 4);

    //        num = r.Next(10, 85);
    //        for (int i = 0; i < num; i++)
    //        {
    //            r4.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }
    //        RaceCompetitor r5 = new RaceCompetitor("Anders", "Stenström", "S45-1", 4777687, 5);

    //        num = r.Next(10, 85);

    //        for (int i = 0; i < num; i++)
    //        {
    //            r5.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }

    //        RaceCompetitor r6 = new RaceCompetitor("Lennart", "Jerksten", "S45-10", 3592932, 6);

    //        num = r.Next(10, 85);
    //        for (int i = 0; i < num; i++)
    //        {
    //            r6.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }
    //        RaceCompetitor r7 = new RaceCompetitor("Staffan", "Zetterlund", "S1-6", 4777687, 7);

    //        num = r.Next(10, 85);

    //        for (int i = 0; i < num; i++)
    //        {
    //            r7.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }

    //        RaceCompetitor r8 = new RaceCompetitor("Stefan", "Larsson", "S8-141", 3592932, 8);

    //        num = r.Next(10, 85);
    //        for (int i = 0; i < num; i++)
    //        {
    //            r8.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }
    //        RaceCompetitor r9 = new RaceCompetitor("Thomas", "Hansen", "D-1722", 4777687, 9);

    //        num = r.Next(10, 85);

    //        for (int i = 0; i < num; i++)
    //        {
    //            r9.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }

    //        RaceCompetitor r10 = new RaceCompetitor("Robert", "Andersson", "S2-47", 3592932, 10);

    //        num = r.Next(10, 85);
    //        for (int i = 0; i < num; i++)
    //        {
    //            r10.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }
    //        RaceCompetitor r11 = new RaceCompetitor("Sven", "Andersson", "S2-46", 4777687, 11);

    //        num = r.Next(10, 85);

    //        for (int i = 0; i < num; i++)
    //        {
    //            r11.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }

    //        RaceCompetitor r12 = new RaceCompetitor("David", "Hammarström", "S8-149", 3592932, 12);

    //        num = r.Next(10, 85);
    //        for (int i = 0; i < num; i++)
    //        {
    //            r12.Laps.Add(new Lap(NextDouble(r, 13, 25), 0, 100));
    //        }


    //        Competitors.Add(r1);
    //        Competitors.Add(r2);
    //        Competitors.Add(r3);
    //        Competitors.Add(r4);
    //        Competitors.Add(r5);
    //        Competitors.Add(r6);
    //        Competitors.Add(r7);
    //        Competitors.Add(r8);
    //        Competitors.Add(r9);
    //        Competitors.Add(r10);
    //        Competitors.Add(r11);
    //        Competitors.Add(r12);

    //        List<RaceCompetitor> SortedCompetitors = new List<RaceCompetitor>(Competitors);


    //        SortedCompetitors.Sort(CompetitorComparison);

    //        //Create Document class object and set its size to letter and give space left, right, Top, Bottom Margin
    //        Document doc = new Document(iTextSharp.text.PageSize.A4.Rotate(), 20, 20, 22, 35);

    //        PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream("Test" + DateTime.Now.ToString("yyyy-MM-dd HH mm") + ".pdf", FileMode.Create));
    //        doc.Open();//Open Document to write


    //        Font Calibri = FontFactory.GetFont("Calibri");
    //        Font CalibriBold = FontFactory.GetFont("Calibri", 10, Font.BOLD);
    //        Font CalibriHeader = FontFactory.GetFont("Calibri", 60, Font.BOLD);

    //        Paragraph paragraph = new Paragraph("2,5spec - Heat 1:2");
    //        paragraph.Font.Size = 30;

    //        PdfPTable ResultTable = new PdfPTable(3);

    //        ResultTable.TotalWidth = 300f;
    //        ResultTable.LockedWidth = true;
    //        ResultTable.SetWidths(new float[] { 4f, 1f, 1f });

    //        ResultTable.HorizontalAlignment = 0;

    //        //leave a gap before and after the table

    //        ResultTable.SpacingBefore = 15f;

    //        ResultTable.SpacingAfter = 15f;

    //        ResultTable.DefaultCell.Padding = 3;
    //        ResultTable.DefaultCell.BorderColor = BaseColor.GRAY;

    //        PdfPTable TimeTable = new PdfPTable(Competitors.Count);
    //        //actual width of table in points

    //        TimeTable.TotalWidth = Competitors.Count * 66f;

    //        //fix the absolute width of the table

    //        TimeTable.LockedWidth = true;



    //        //relative col widths in proportions - 1/3 and 2/3

    //        float[] widths = new float[] { 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f };

    //        TimeTable.SetWidths(widths);

    //        TimeTable.HorizontalAlignment = 0;

    //        //leave a gap before and after the table

    //        TimeTable.SpacingBefore = 15f;

    //        TimeTable.SpacingAfter = 15f;

    //        SortedCompetitors.Reverse();

    //        double bestofall = 30*1000;

    //        foreach (RaceCompetitor boa in SortedCompetitors)
    //        {
    //            if (boa.BestLap <= bestofall)
    //                bestofall = boa.BestLap;
    //        }

    //        int Position = 1;
    //        foreach (RaceCompetitor c in SortedCompetitors)
    //        {
    //            Font b = FontFactory.GetFont(FontFactory.HELVETICA);
    //            if (c.BestLap == bestofall)
    //                b = FontFactory.GetFont(FontFactory.HELVETICA_BOLD);

    //            b.Size = 12;

    //            Chunk n = new Chunk(Position+". "+c.FirstName + " " + c.SurName, b);
    //            Phrase pName = new Phrase(n);

    //            Chunk l = new Chunk(c.Laps.Count.ToString(), b);
    //            Phrase pLaps = new Phrase(l);

    //            Chunk be = new Chunk(c.BestLap.ToString(), b);
    //            Phrase pBest = new Phrase(be);

    //            ResultTable.AddCell(pName);
    //            ResultTable.AddCell(pLaps);
    //            ResultTable.AddCell(pBest);

    //            Position++;
    //        }


    //        foreach (RaceCompetitor t in Competitors)
    //        {
    //            Phrase ps = new Phrase();

    //            Font b = CalibriBold;
    //            b.SetStyle(1);
    //            b.Size = 7;

    //            Chunk g = new Chunk(t.LicenceNumber + Environment.NewLine + t.FirstName.Substring(0, 1) + ". " + t.SurName + Environment.NewLine, b);

    //            ps.Add(g);

    //            int c = 0;

    //            double best = t.BestLap;

    //            foreach (Lap l in t.Laps)
    //            {


    //                c++;
    //                if (l.LapTime == best)
    //                {
    //                    Font bt = CalibriBold;
    //                    bt.SetStyle(1);
    //                    bt.Size = 9;

    //                    ps.Add(new Chunk(c.ToString("00") + " | " + l.LapTime + Environment.NewLine, bt));

    //                }
    //                else
    //                {
    //                    Font bt = Calibri;
    //                    bt.SetStyle(0);
    //                    bt.Size = 9;
    //                    ps.Add(new Chunk(c.ToString("00") + " | " + l.LapTime + Environment.NewLine, bt));
    //                }
    //            }

    //            PdfPCell pc = new PdfPCell(ps);

    //            pc.Border = 0;

    //            TimeTable.AddCell(pc);
    //        }

    //        doc.Add(paragraph);

    //        doc.Add(ResultTable);

    //        doc.Add(TimeTable);

    //        doc.Close(); //Close document
    //    }

    //    public static Comparison<RaceCompetitor> CompetitorComparison =
    //    delegate(RaceCompetitor p1, RaceCompetitor p2)
    //    {
    //        return p1.Laps.Count.CompareTo(p2.Laps.Count);
    //    };

    //    static double NextDouble(Random rng, double min, double max)
    //    {
    //        return min + (rng.NextDouble() * (max - min));
    //    }
    //}
}
